# GoFilm 项目 Makefile
# 支持前端Vue项目和后端Go项目的构建、运行、测试等操作

# 项目信息
PROJECT_NAME := GoFilm
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "v1.0.0")
BUILD_TIME := $(shell date +%Y-%m-%d\ %H:%M:%S)
GO_VERSION := $(shell go version | cut -d ' ' -f 3)

# 目录定义
CLIENT_DIR := client
SERVER_DIR := server
DIST_DIR := dist
BUILD_DIR := build

# Go相关变量
GO_MODULE := server
GO_MAIN := $(SERVER_DIR)/main.go
GO_BINARY := $(BUILD_DIR)/gofilm
GO_LDFLAGS := -ldflags "-X main.Version=$(VERSION) -X main.BuildTime=$(BUILD_TIME) -X main.GoVersion=$(GO_VERSION)"

# Node.js相关变量
NODE_MODULES := $(CLIENT_DIR)/node_modules
PACKAGE_JSON := $(CLIENT_DIR)/package.json

# 颜色定义
RED := \033[31m
GREEN := \033[32m
YELLOW := \033[33m
BLUE := \033[34m
RESET := \033[0m

# 默认目标
.DEFAULT_GOAL := help

# 帮助信息
.PHONY: help
help: ## 显示帮助信息
	@echo "$(BLUE)$(PROJECT_NAME) $(VERSION)$(RESET)"
	@echo "$(BLUE)===========================================$(RESET)"
	@echo ""
	@echo "$(YELLOW)可用命令:$(RESET)"
	@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "  $(GREEN)%-20s$(RESET) %s\n", $$1, $$2}' $(MAKEFILE_LIST)
	@echo ""
	@echo "$(YELLOW)示例:$(RESET)"
	@echo "  make install     # 安装所有依赖"
	@echo "  make dev         # 启动开发环境"
	@echo "  make build       # 构建生产版本"
	@echo "  make clean       # 清理构建文件"

# ==================== 安装和初始化 ====================

.PHONY: install
install: install-client install-server ## 安装前端和后端依赖

.PHONY: install-client
install-client: ## 安装前端依赖
	@echo "$(BLUE)安装前端依赖...$(RESET)"
	cd $(CLIENT_DIR) && npm install
	@echo "$(GREEN)✅ 前端依赖安装完成$(RESET)"

.PHONY: install-server
install-server: ## 安装后端依赖
	@echo "$(BLUE)安装后端依赖...$(RESET)"
	cd $(SERVER_DIR) && go mod download
	cd $(SERVER_DIR) && go mod tidy
	@echo "$(GREEN)✅ 后端依赖安装完成$(RESET)"

.PHONY: init
init: install check-env ## 初始化项目环境
	@echo "$(BLUE)初始化项目环境...$(RESET)"
	mkdir -p $(BUILD_DIR)
	mkdir -p $(DIST_DIR)
	mkdir -p $(SERVER_DIR)/static/hls
	@echo "$(GREEN)✅ 项目初始化完成$(RESET)"

# ==================== 开发环境 ====================

.PHONY: dev
dev: ## 启动开发环境（前端+后端）
	@echo "$(BLUE)启动开发环境...$(RESET)"
	@$(MAKE) -j2 dev-client dev-server

.PHONY: dev-client
dev-client: $(NODE_MODULES) ## 启动前端开发服务器
	@echo "$(BLUE)启动前端开发服务器...$(RESET)"
	cd $(CLIENT_DIR) && npm run dev

.PHONY: dev-server
dev-server: ## 启动后端开发服务器
	@echo "$(BLUE)启动后端开发服务器...$(RESET)"
	cd $(SERVER_DIR) && go run $(GO_MAIN)

.PHONY: dev-hls
dev-hls: ## 启动HLS流媒体演示
	@echo "$(BLUE)启动HLS流媒体演示...$(RESET)"
	cd $(SERVER_DIR) && chmod +x start_hls_demo.sh && ./start_hls_demo.sh

# ==================== 构建 ====================

.PHONY: build
build: build-client build-server ## 构建前端和后端

.PHONY: build-client
build-client: $(NODE_MODULES) ## 构建前端生产版本
	@echo "$(BLUE)构建前端生产版本...$(RESET)"
	cd $(CLIENT_DIR) && npm run build
	@echo "$(GREEN)✅ 前端构建完成$(RESET)"

.PHONY: build-server
build-server: ## 构建后端二进制文件
	@echo "$(BLUE)构建后端二进制文件...$(RESET)"
	mkdir -p $(BUILD_DIR)
	cd $(SERVER_DIR) && go build $(GO_LDFLAGS) -o ../$(GO_BINARY) $(GO_MAIN)
	@echo "$(GREEN)✅ 后端构建完成: $(GO_BINARY)$(RESET)"

.PHONY: build-linux
build-linux: ## 构建Linux版本
	@echo "$(BLUE)构建Linux版本...$(RESET)"
	mkdir -p $(BUILD_DIR)
	cd $(SERVER_DIR) && GOOS=linux GOARCH=amd64 go build $(GO_LDFLAGS) -o ../$(BUILD_DIR)/gofilm-linux-amd64 $(GO_MAIN)
	@echo "$(GREEN)✅ Linux版本构建完成$(RESET)"

.PHONY: build-windows
build-windows: ## 构建Windows版本
	@echo "$(BLUE)构建Windows版本...$(RESET)"
	mkdir -p $(BUILD_DIR)
	cd $(SERVER_DIR) && GOOS=windows GOARCH=amd64 go build $(GO_LDFLAGS) -o ../$(BUILD_DIR)/gofilm-windows-amd64.exe $(GO_MAIN)
	@echo "$(GREEN)✅ Windows版本构建完成$(RESET)"

.PHONY: build-darwin
build-darwin: ## 构建macOS版本
	@echo "$(BLUE)构建macOS版本...$(RESET)"
	mkdir -p $(BUILD_DIR)
	cd $(SERVER_DIR) && GOOS=darwin GOARCH=amd64 go build $(GO_LDFLAGS) -o ../$(BUILD_DIR)/gofilm-darwin-amd64 $(GO_MAIN)
	@echo "$(GREEN)✅ macOS版本构建完成$(RESET)"

.PHONY: build-all
build-all: build-client build-linux build-windows build-darwin ## 构建所有平台版本

# ==================== 测试 ====================

.PHONY: test
test: test-client test-server ## 运行前端和后端测试

.PHONY: test-client
test-client: $(NODE_MODULES) ## 运行前端测试
	@echo "$(BLUE)运行前端测试...$(RESET)"
	cd $(CLIENT_DIR) && npm run test 2>/dev/null || echo "$(YELLOW)⚠️  前端测试脚本未配置$(RESET)"

.PHONY: test-server
test-server: ## 运行后端测试
	@echo "$(BLUE)运行后端测试...$(RESET)"
	cd $(SERVER_DIR) && go test -v ./...

.PHONY: test-hls
test-hls: ## 测试HLS服务
	@echo "$(BLUE)测试HLS服务...$(RESET)"
	cd $(SERVER_DIR) && go run test_hls.go

# ==================== 代码质量 ====================

.PHONY: lint
lint: lint-client lint-server ## 运行代码检查

.PHONY: lint-client
lint-client: $(NODE_MODULES) ## 运行前端代码检查
	@echo "$(BLUE)运行前端代码检查...$(RESET)"
	cd $(CLIENT_DIR) && npm run lint 2>/dev/null || echo "$(YELLOW)⚠️  前端lint脚本未配置$(RESET)"

.PHONY: lint-server
lint-server: ## 运行后端代码检查
	@echo "$(BLUE)运行后端代码检查...$(RESET)"
	cd $(SERVER_DIR) && go vet ./...
	cd $(SERVER_DIR) && go fmt ./...

.PHONY: fmt
fmt: ## 格式化代码
	@echo "$(BLUE)格式化后端代码...$(RESET)"
	cd $(SERVER_DIR) && go fmt ./...
	@echo "$(GREEN)✅ 代码格式化完成$(RESET)"

# ==================== 部署 ====================

.PHONY: package
package: build ## 打包发布版本
	@echo "$(BLUE)打包发布版本...$(RESET)"
	mkdir -p $(DIST_DIR)
	cp -r $(CLIENT_DIR)/dist $(DIST_DIR)/web
	cp $(GO_BINARY) $(DIST_DIR)/
	cp -r $(SERVER_DIR)/static $(DIST_DIR)/
	cp $(SERVER_DIR)/config $(DIST_DIR)/ 2>/dev/null || true
	@echo "$(GREEN)✅ 打包完成: $(DIST_DIR)/$(RESET)"

.PHONY: docker-build
docker-build: ## 构建Docker镜像
	@echo "$(BLUE)构建Docker镜像...$(RESET)"
	docker build -t $(PROJECT_NAME):$(VERSION) .
	docker tag $(PROJECT_NAME):$(VERSION) $(PROJECT_NAME):latest
	@echo "$(GREEN)✅ Docker镜像构建完成$(RESET)"

.PHONY: docker-run
docker-run: ## 运行Docker容器
	@echo "$(BLUE)运行Docker容器...$(RESET)"
	docker run -d -p 8080:8080 --name $(PROJECT_NAME) $(PROJECT_NAME):latest

# ==================== 数据库 ====================

.PHONY: db-migrate
db-migrate: ## 运行数据库迁移
	@echo "$(BLUE)运行数据库迁移...$(RESET)"
	cd $(SERVER_DIR) && go run $(GO_MAIN) -migrate
	@echo "$(GREEN)✅ 数据库迁移完成$(RESET)"

.PHONY: db-seed
db-seed: ## 初始化数据库数据
	@echo "$(BLUE)初始化数据库数据...$(RESET)"
	cd $(SERVER_DIR) && go run $(GO_MAIN) -seed
	@echo "$(GREEN)✅ 数据库数据初始化完成$(RESET)"

# ==================== 代码生成 ====================

.PHONY: gen-install
gen-install: ## 安装代码生成工具依赖
	@echo "$(BLUE)安装代码生成工具依赖...$(RESET)"
	cd $(SERVER_DIR) && chmod +x tools/install_deps.sh && ./tools/install_deps.sh
	@echo "$(GREEN)✅ 代码生成工具依赖安装完成$(RESET)"

.PHONY: gen-models
gen-models: ## 生成GORM模型（简单模式）
	@echo "$(BLUE)生成GORM模型...$(RESET)"
	cd $(SERVER_DIR) && go run tools/simple_gen.go
	@echo "$(GREEN)✅ GORM模型生成完成$(RESET)"

.PHONY: gen-models-advanced
gen-models-advanced: ## 生成GORM模型（高级模式）
	@echo "$(BLUE)生成GORM模型（高级模式）...$(RESET)"
	cd $(SERVER_DIR) && go run tools/gen.go
	@echo "$(GREEN)✅ GORM模型生成完成$(RESET)"

.PHONY: gen-models-config
gen-models-config: ## 生成GORM模型（配置文件模式）
	@echo "$(BLUE)生成GORM模型（配置文件模式）...$(RESET)"
	cd $(SERVER_DIR) && go run tools/advanced_gen.go
	@echo "$(GREEN)✅ GORM模型生成完成$(RESET)"

.PHONY: gen-clean
gen-clean: ## 清理生成的模型文件
	@echo "$(BLUE)清理生成的模型文件...$(RESET)"
	rm -rf $(SERVER_DIR)/model/db_model/*
	@echo "$(GREEN)✅ 模型文件清理完成$(RESET)"

# ==================== 清理 ====================

.PHONY: clean
clean: ## 清理构建文件
	@echo "$(BLUE)清理构建文件...$(RESET)"
	rm -rf $(BUILD_DIR)
	rm -rf $(DIST_DIR)
	rm -rf $(CLIENT_DIR)/dist
	rm -rf $(SERVER_DIR)/static/hls/*
	@echo "$(GREEN)✅ 清理完成$(RESET)"

.PHONY: clean-deps
clean-deps: ## 清理依赖文件
	@echo "$(BLUE)清理依赖文件...$(RESET)"
	rm -rf $(NODE_MODULES)
	cd $(SERVER_DIR) && go clean -modcache
	@echo "$(GREEN)✅ 依赖清理完成$(RESET)"

.PHONY: clean-all
clean-all: clean clean-deps ## 清理所有文件

# ==================== 工具 ====================

.PHONY: logs
logs: ## 查看应用日志
	@echo "$(BLUE)查看应用日志...$(RESET)"
	tail -f $(SERVER_DIR)/logs/*.log 2>/dev/null || echo "$(YELLOW)⚠️  日志文件不存在$(RESET)"

.PHONY: ps
ps: ## 查看运行状态
	@echo "$(BLUE)查看运行状态...$(RESET)"
	@ps aux | grep -E "(gofilm|node.*vite)" | grep -v grep || echo "$(YELLOW)⚠️  未找到运行中的进程$(RESET)"

.PHONY: version
version: ## 显示版本信息
	@echo "$(BLUE)版本信息:$(RESET)"
	@echo "  项目: $(PROJECT_NAME)"
	@echo "  版本: $(VERSION)"
	@echo "  构建时间: $(BUILD_TIME)"
	@echo "  Go版本: $(GO_VERSION)"

.PHONY: info
info: ## 显示项目信息
	@echo "$(BLUE)项目信息:$(RESET)"
	@echo "  项目名称: $(PROJECT_NAME)"
	@echo "  项目版本: $(VERSION)"
	@echo "  前端目录: $(CLIENT_DIR)"
	@echo "  后端目录: $(SERVER_DIR)"
	@echo "  构建目录: $(BUILD_DIR)"
	@echo "  发布目录: $(DIST_DIR)"

# ==================== 环境检查 ====================

.PHONY: check-env
check-env: ## 检查开发环境
	@echo "$(BLUE)检查开发环境...$(RESET)"
	@command -v node >/dev/null 2>&1 || (echo "$(RED)❌ Node.js 未安装$(RESET)" && exit 1)
	@command -v npm >/dev/null 2>&1 || (echo "$(RED)❌ npm 未安装$(RESET)" && exit 1)
	@command -v go >/dev/null 2>&1 || (echo "$(RED)❌ Go 未安装$(RESET)" && exit 1)
	@command -v git >/dev/null 2>&1 || (echo "$(RED)❌ Git 未安装$(RESET)" && exit 1)
	@echo "$(GREEN)✅ 开发环境检查通过$(RESET)"
	@echo "  Node.js: $$(node --version)"
	@echo "  npm: $$(npm --version)"
	@echo "  Go: $$(go version | cut -d ' ' -f 3)"
	@echo "  Git: $$(git --version | cut -d ' ' -f 3)"

.PHONY: check-ffmpeg
check-ffmpeg: ## 检查FFmpeg安装
	@echo "$(BLUE)检查FFmpeg安装...$(RESET)"
	@command -v ffmpeg >/dev/null 2>&1 && echo "$(GREEN)✅ FFmpeg 已安装: $$(ffmpeg -version | head -n1)$(RESET)" || echo "$(RED)❌ FFmpeg 未安装，HLS功能将无法使用$(RESET)"

# ==================== 依赖规则 ====================

$(NODE_MODULES): $(PACKAGE_JSON)
	@echo "$(BLUE)安装前端依赖...$(RESET)"
	cd $(CLIENT_DIR) && npm install
	@touch $(NODE_MODULES)

# ==================== 快捷命令 ====================

.PHONY: up
up: init dev ## 快速启动（初始化+开发环境）

.PHONY: restart
restart: ## 重启服务
	@echo "$(BLUE)重启服务...$(RESET)"
	@pkill -f "gofilm\|vite" 2>/dev/null || true
	@sleep 2
	@$(MAKE) dev

.PHONY: status
status: ps ## 查看状态（ps的别名）

.PHONY: stop
stop: ## 停止所有服务
	@echo "$(BLUE)停止所有服务...$(RESET)"
	@pkill -f "gofilm\|vite" 2>/dev/null || true
	@echo "$(GREEN)✅ 服务已停止$(RESET)"